<template>
    <div class="box">
        <el-form :model="filmFormData" :rules="rules" ref="filmFormRef" label-width="100px">
            <el-row :gutter="20">
                <el-col :span="12">
                    <el-form-item label="电影名称" prop="name">
                        <el-input v-model="filmFormData.name"></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="电影导演" prop="director">
                        <el-input v-model="filmFormData.director"></el-input>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row :gutter="20">
                <el-col :span="12">
                    <el-form-item label="电影片长" prop="movie_long">
                        <el-input-number v-model.number="filmFormData.movie_long"></el-input-number>
                        <span> 分钟</span>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="综合评分" prop="score">
                        <el-input-number :precision="1" :step="0.1" :max="10" :min="1"
                            v-model.number="filmFormData.score"></el-input-number>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row :gutter="20">
                <el-col :span="12">
                    <el-form-item label="想看人数" prop="wish_num">
                        <el-input-number :step="1000" v-model.number="filmFormData.wish_num"></el-input-number>
                        <span> 人</span>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="电影语言" prop="language">
                        <el-select v-model="filmFormData.language" placeholder="请选择">
                            <el-option label="国语" value="国语"> </el-option>
                            <el-option label="粤语" value="粤语"> </el-option>
                            <el-option label="英语" value="英语"> </el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row :gutter="20">
                <el-col :span="12">
                    <el-form-item label="电影类型" prop="type">
                        <el-select v-model="filmFormData.type" placeholder="请选择">
                            <el-option label="动作片" value="动作片"> </el-option>
                            <el-option label="喜剧片" value="喜剧片"> </el-option>
                            <el-option label="爱情片" value="爱情片"> </el-option>
                            <el-option label="科幻片" value="科幻片"> </el-option>
                            <el-option label="悬疑片" value="悬疑片"> </el-option>
                            <el-option label="恐怖片" value="恐怖片"> </el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="上映时间" prop="public_date">
                        <el-date-picker v-model="filmFormData.public_date" value-format="yyyy-MM-dd" type="date"
                            placeholder="选择日期">
                        </el-date-picker>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row :gutter="20">
                <el-col :span="12">
                    <el-form-item label="电影海报" prop="poster">
                        <el-upload drag action="" :multiple="false" :show-file-list="false" :before-upload="onUploadPoster"
                            accept=".jpg,.jpeg,.png,.gif">
                            <i class="el-icon-upload"></i>
                            <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
                            <div class="el-upload__tip" slot="tip">只能上传jpg/png/gif文件，且不超过10MB</div>
                        </el-upload>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <!-- <el-image :src="poster" style="width: 260px"></el-image> -->
                    <img :src="poster" style="width: 260px" />
                </el-col>
            </el-row>
            <el-row :gutter="20">
                <el-col :span="12">
                    <el-form-item label="电影预告" prop="video">
                        <el-upload drag action="" :multiple="false" :show-file-list="false" :before-upload="onUploadVideo"
                            accept=".mp4,.wmv,.mov,.avi">
                            <i class="el-icon-upload"></i>
                            <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
                            <div class="el-upload__tip" slot="tip">只能上传.mp4,.wmv,.mov,.avi文件</div>
                        </el-upload>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <!-- 视频播放 -->
                    <video :src="video" controls style="width: 260px"></video>
                </el-col>
            </el-row>
            <el-row :gutter="20">
                <el-col :span="24">
                    <!-- 动态表单 -->
                    <el-form-item v-for="(actor, index) in filmFormData.actor" :label="'演员' + (index === 0 ? '' : index)"
                        :key="index" :prop="'actor.' + index + '.value'" :rules="{
                            required: true,
                            message: '演员名称不能为空',
                            trigger: 'blur'
                        }">
                        <el-input v-model="actor.value" style="width: 300px"></el-input>
                        <span style="margin-left: 10px">
                            <el-button v-if="index === 0" type="primary" @click.prevent="addActor">
                                新增
                            </el-button>
                            <el-button v-else @click.prevent="removeActor(index)">删除</el-button>
                        </span>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row :gutter="20">
                <el-col :span="24">
                    <el-form-item label="电影简介" prop="intro">
                        <el-input type="textarea" :rows="5" resize="none" v-model="filmFormData.intro" />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row :gutter="20">
                <el-form-item>
                    <el-button type="primary" @click="submitForm">新增电影信息</el-button>
                    <el-button @click="resetForm">重置</el-button>
                </el-form-item>
            </el-row>
        </el-form>
    </div>
</template>

<script>
import { getFullYearDay, fileContentToHash, delay } from '@/utils/tools'
//引入表单验证方式
import formValidateMixin from './mixin'
//引入请求接口
import { uploadFilmPosterApi, uploadChunkVideoApi, mergeVideoApi, addFilmApi } from '@/api/filmApi'

export default {
    mixins: [formValidateMixin],
    data() {
        return {
            poster: 'http://localhost:5000/users/1699001266233_5a1b17f8.jpg',
            video: '',
            filmFormData: {
                name: '',
                director: '',
                movie_long: 120,
                score: 10.0,
                wish_num: 300000,
                language: '国语',
                type: '',
                public_date: getFullYearDay(7, 'day')[0],
                actor: [
                    {
                        value: ''
                    }
                ],
                intro: '',
                video: '',
                poster: ''
            }
        }
    },
    methods: {
        // 海报图片上传处理操作
        async onUploadPoster(file) {
            // console.log(file);    打印file查看其属性
            // 限制上传图片只能小于或等一载10mb
            if (file.size > 1024 * 1024 * 10) {
                this.$message({
                    message: '当前上传的图片过大,超过10MB',
                    type: 'error',
                    showClose: true,
                    duration: 3000
                })
                return false
            }
            // 限制上传图片只能是图片
            let allowImage = ['image/jpeg', 'image/gif', 'image/png']
            //判断文件类型是否为图片格式
            const isType = allowImage.includes(file.type)
            if (!isType) {
                this.$message({
                    message: '当前上传的图片是一个不合法的文件,只能上传图片',
                    type: 'error',
                    showClose: true,
                    duration: 3000
                })
                return false
            }

            // 上传图片 FormData
            const formData = new FormData()
            formData.append('file', file)
            const ret = await uploadFilmPosterApi(formData)
            if (ret.code === 0) {
                this.filmFormData.poster = ret.data.path
                this.poster = ret.data.url
            }
        },
        // 预告视频上传处理操作
        // 预告片它的文件大小可能会很大，而服务器单个请求可能只能接受2M左右，此时就可以上传不成功了
        // 此时就需要进行把文件拆分成若干个小的文件，然后进行上传处理
        // 大文件上传的方案
        //  + 固定数量，进行拆分文件，数量固定，但单个拆分的文件大小不固定
        //  + 固定文件大小，进行拆分文件，单个拆分的文件大小固定，但数量不固定
        // 拆分后的文件，如何在后台中进行组合成一个完整的文件呢？
        //  + 拆分之前后给当前的文件按内容进行一次hash运算得到一个唯一字符串，此字符串就是此文件在标识，然后在给拆分的小块进行编写 aabeewf_1,aabeewf_2,aabeewf_3
        //   FileReader  spark-md5库
        //   File对象能不能进行切割？ 能，它也是继承了Blob块，它里面有一个slice方法，专门用来切割的
        // 上传之前可以进行验证，是否可上传 ping过程,它就是把文件切一个很小很小的片，可以是1kb左右，进行尝试上传，如果成功表示，可以继续上传，这样可确保上传的成功率。
        async onUploadVideo(file) {
            // 上传视图不能超过100mb
            if (file.size > 1024 * 1024 * 100) {
                this.$message({
                    message: '当前上传的视频过大,超过100MB',
                    type: 'error',
                    showClose: true,
                    duration: 3000
                })
                return false
            }
            // 上传只能上传.mp4,.wmv,.mov,.avi文件格式
            if (!['video/mp4', 'video/wmv', 'video/avi'].includes(file.type)) {
                this.$message({
                    message: '当前上传的视频是一个不合法的文件,只能上传.mp4,.wmv,.mov,.avi文件格式',
                    type: 'error',
                    showClose: true,
                    duration: 3000
                })
                return false
            }
            // 进行大文件上传操作处理，按固定数量进行拆分上传
            // 拆分的数量为5块
            const partNum = 5
            // 计算拆分后每块的大小
            const partSize = file.size / partNum
            // https://www.jianshu.com/p/b89634e4eb3b
            // 按文件内容进行计算出来的hash值，用于上传后文件所用
            // npm i -S spark-md5
            // 根据文件内容生成对应的hash值，用于上传所用
            // 可以做秒传
            const hash = await fileContentToHash(file)
            // 获取扩展名
            const extname = file.name.slice(file.name.lastIndexOf('.'))



            // 进行文件切割
            const chunkFiles = []       //切割文件的大小
            const chunkNames = []       //切割文件的名称
            // 循环进行文件切割
            for (let i = 0; i < partNum; i++) {
                // 设置文件切割的头部和尾部
                let start = i * partSize
                let end = start + partSize
                // 按照规定的头尾进行切割，切割后存入数组
                chunkFiles.push(file.slice(start, end))
                // 存放每个文件的文件名
                chunkNames.push(hash + '_' + i + extname)
            }
            // formData进行上传方式
            // 一次性全上传完，还是一个个的上传
            // 多个请求，可以用Promise.all
            // Promise.allSettled  es12标准提供的，它的兼容差一些，它可以知道哪些出现了异常
            // Promise.all 只要有一个失败它就是失败，但不知道是哪一个是失败的
            // 浏览器它本身可能对于并发有一些要求,http1.x=>3-5之间，http2.x会更多一些

            // 得到多个请求
            let requests = []
            for (let i = 0; i < partNum; i++) {
                const formData = new FormData()
                formData.append('name', chunkNames[i])
                formData.append('file', chunkFiles[i])
                const fn = (() => uploadChunkVideoApi(formData))()
                requests.push(fn)
                // requests.push(() => uploadChunkVideoApi(formData))
            }
            Promise.all(requests)
                .then(rets => {
                    console.log(rets, 126);
                }).catch(() => {
                    console.log("bxkjabkjdbja");
                })
        },
        // 新增电影表单提交
        submitForm() {
            this.$refs.filmFormRef.validate(async valid => {
                if (valid) {
                    //验证成功
                    let filmData = {
                        // 展开对象
                        ...this.filmFormData,
                        // 将actor重新进行数据清洗
                        actor: this.filmFormData.actor.map(item => item.value).join(',')
                    }
                    console.log(filmData);
                }
            })
        },
        // 新增演员
        addActor() {
            if (this.filmFormData.actor.length > 10) {
                this.$message({
                    message: '最多添加10个演员',
                    type: 'error',
                    showClose: true,
                    duration: 3000
                })
                return
            }
            //点击后新增表单框，实现添加演员
            this.filmFormData.actor.push({
                value: ''
            })
        },
        // 删除演员
        removeActor(index) {
            this.filmFormData.actor.splice(index, 1)
        },
        // 重置电影表单提交
        resetForm() {
            this.$refs.filmFormRef.resetFields()
        }
    },
}

</script>


<style scoped>
.box {
    padding: 10px;
    background: #fff;
    min-height: 100%;
}
</style>